package com.school.sports.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 志愿者任务表实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("volunteer_task")
public class VolunteerTask {

    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 志愿者ID（关联用户表）
     */
    @NotNull(message = "志愿者ID不能为空")
    private Long volunteerId;

    /**
     * 项目ID
     */
    private Long projectId;

    /**
     * 场地ID
     */
    private Integer venueId;

    /**
     * 任务内容
     */
    @NotBlank(message = "任务内容不能为空")
    @Size(max = 2000, message = "任务内容长度不能超过2000个字符")
    private String taskContent;

    /**
     * 开始时间
     */
    @NotNull(message = "开始时间不能为空")
    private LocalDateTime startTime;

    /**
     * 结束时间
     */
    private LocalDateTime endTime;

    /**
     * 状态：未开始、进行中、已完成、已取消
     */
    private String status;

    /**
     * 志愿者反馈
     */
    @Size(max = 1000, message = "志愿者反馈长度不能超过1000个字符")
    private String feedback;

    /**
     * 评分：优秀、良好、合格、不合格
     */
    private String rating;

    /**
     * 创建时间
     */
    private LocalDateTime createdAt;

    /**
     * 志愿者对象（关联查询时使用）
     */
    @TableField(exist = false)
    private User volunteer;

    /**
     * 项目对象（关联查询时使用）
     */
    @TableField(exist = false)
    private Project project;

    /**
     * 场地对象（关联查询时使用）
     */
    @TableField(exist = false)
    private Venue venue;

    /**
     * 志愿者姓名（关联查询时使用）
     */
    @TableField(exist = false)
    private String volunteerName;

    /**
     * 项目名称（关联查询时使用）
     */
    @TableField(exist = false)
    private String projectName;

    /**
     * 场地名称（关联查询时使用）
     */
    @TableField(exist = false)
    private String venueName;

    /**
     * 服务时长（计算字段）
     */
    @TableField(exist = false)
    private Integer serviceHours;

    /**
     * 任务状态枚举
     */
    public enum TaskStatus {
        NOT_STARTED("未开始"),
        IN_PROGRESS("进行中"),
        COMPLETED("已完成"),
        CANCELLED("已取消");

        private final String displayName;

        TaskStatus(String displayName) {
            this.displayName = displayName;
        }

        public String getDisplayName() {
            return displayName;
        }

        /**
         * 根据显示名称获取枚举值
         */
        public static TaskStatus fromDisplayName(String displayName) {
            for (TaskStatus status : TaskStatus.values()) {
                if (status.getDisplayName().equals(displayName)) {
                    return status;
                }
            }
            return null;
        }
    }

    /**
     * 任务评分枚举
     */
    public enum TaskRating {
        EXCELLENT("优秀", 5.0),
        GOOD("良好", 4.0),
        QUALIFIED("合格", 3.0),
        UNQUALIFIED("不合格", 1.0);

        private final String displayName;
        private final Double numericValue;

        TaskRating(String displayName, Double numericValue) {
            this.displayName = displayName;
            this.numericValue = numericValue;
        }

        public String getDisplayName() {
            return displayName;
        }

        public Double getNumericValue() {
            return numericValue;
        }

        /**
         * 根据显示名称获取枚举值
         */
        public static TaskRating fromDisplayName(String displayName) {
            for (TaskRating rating : TaskRating.values()) {
                if (rating.getDisplayName().equals(displayName)) {
                    return rating;
                }
            }
            return null;
        }
    }

    /**
     * 设置任务状态
     */
    public void setStatus(String status) {
        this.status = status;
    }

    /**
     * 获取任务状态显示名称
     */
    public String getStatusDisplayName() {
        TaskStatus statusEnum = TaskStatus.fromDisplayName(this.status);
        return statusEnum != null ? statusEnum.getDisplayName() : this.status;
    }

    /**
     * 检查是否未开始
     */
    public boolean isNotStarted() {
        return TaskStatus.NOT_STARTED.getDisplayName().equals(this.status);
    }

    /**
     * 检查是否进行中
     */
    public boolean isInProgress() {
        return TaskStatus.IN_PROGRESS.getDisplayName().equals(this.status);
    }

    /**
     * 检查是否已完成
     */
    public boolean isCompleted() {
        return TaskStatus.COMPLETED.getDisplayName().equals(this.status);
    }

    /**
     * 检查是否已取消
     */
    public boolean isCancelled() {
        return TaskStatus.CANCELLED.getDisplayName().equals(this.status);
    }

    /**
     * 开始任务
     */
    public void startTask() {
        if (isNotStarted()) {
            this.status = TaskStatus.IN_PROGRESS.getDisplayName();
        }
    }

    /**
     * 完成任务
     */
    public void completeTask() {
        this.status = TaskStatus.COMPLETED.getDisplayName();
        // 如果没有结束时间，设置为当前时间
        if (endTime == null) {
            endTime = LocalDateTime.now();
        }
    }

    /**
     * 取消任务
     */
    public void cancelTask() {
        this.status = TaskStatus.CANCELLED.getDisplayName();
    }

    /**
     * 设置任务评分
     */
    public void setRating(String rating) {
        this.rating = rating;
    }

    /**
     * 获取评分显示名称
     */
    public String getRatingDisplayName() {
        TaskRating ratingEnum = TaskRating.fromDisplayName(this.rating);
        return ratingEnum != null ? ratingEnum.getDisplayName() : this.rating;
    }

    /**
     * 获取评分数值
     */
    public Double getRatingValue() {
        TaskRating ratingEnum = TaskRating.fromDisplayName(this.rating);
        return ratingEnum != null ? ratingEnum.getNumericValue() : null;
    }

    /**
     * 检查是否可以修改状态
     */
    public boolean canModifyStatus() {
        return !isCompleted() && !isCancelled();
    }

    /**
     * 检查任务是否有效
     */
    public boolean isValid() {
        return volunteerId != null && taskContent != null && !taskContent.trim().isEmpty() && startTime != null;
    }

    /**
     * 计算服务时长
     */
    public Integer calculateServiceHours() {
        if (startTime == null) return 0;

        LocalDateTime endTimeToUse = endTime != null ? endTime : LocalDateTime.now();
        Duration duration = Duration.between(startTime, endTimeToUse);

        long hours = duration.toHours();
        long minutes = duration.toMinutes() % 60;
        if (minutes >= 30) {
            hours++; // 超过30分钟按一小时计算
        }

        return (int) Math.max(0, hours);
    }

    /**
     * 获取服务时长显示
     */
    public String getServiceHoursDisplay() {
        if (serviceHours == null) {
            serviceHours = calculateServiceHours();
        }
        return serviceHours + " 小时";
    }

    /**
     * 获取任务显示信息
     */
    public String getTaskDisplay() {
        StringBuilder display = new StringBuilder();
        display.append(volunteerName != null ? volunteerName : "未知志愿者");

        if (projectName != null) {
            display.append(" - ").append(projectName);
        }

        display.append(" (").append(getStatusDisplayName()).append(")");

        return display.toString();
    }

    /**
     * 获取状态标签样式（用于前端显示）
     */
    public String getStatusTagType() {
        if (isNotStarted()) return "info";
        if (isInProgress()) return "warning";
        if (isCompleted()) return "success";
        if (isCancelled()) return "danger";
        return "info";
    }

    /**
     * 获取评分标签样式
     */
    public String getRatingTagType() {
        if (rating == null) return "info";

        TaskRating ratingEnum = TaskRating.fromDisplayName(rating);
        if (ratingEnum == null) return "info";

        switch (ratingEnum) {
            case EXCELLENT: return "success";
            case GOOD: return "primary";
            case QUALIFIED: return "warning";
            case UNQUALIFIED: return "danger";
            default: return "info";
        }
    }

    /**
     * 获取任务类型
     */
    public String getTaskType() {
        if (projectId != null && venueId != null) {
            return "项目+场地服务";
        } else if (projectId != null) {
            return "项目服务";
        } else if (venueId != null) {
            return "场地服务";
        } else {
            return "通用服务";
        }
    }

    /**
     * 检查任务是否过期
     */
    public boolean isExpired() {
        return endTime != null && endTime.isBefore(LocalDateTime.now()) && !isCompleted();
    }

    /**
     * 检查任务是否即将开始（1小时内）
     */
    public boolean isStartingSoon() {
        return startTime != null &&
               startTime.isAfter(LocalDateTime.now()) &&
               startTime.isBefore(LocalDateTime.now().plusHours(1)) &&
               isNotStarted();
    }

    /**
     * 检查任务是否进行中
     */
    public boolean isCurrentlyActive() {
        LocalDateTime now = LocalDateTime.now();
        return startTime != null && startTime.isBefore(now) &&
               (endTime == null || endTime.isAfter(now)) &&
               isInProgress();
    }

    /**
     * 获取任务优先级
     */
    public String getTaskPriority() {
        if (isStartingSoon()) return "紧急";
        if (isCurrentlyActive()) return "进行中";
        if (isExpired()) return "已过期";
        return "正常";
    }

    /**
     * 从关联对象同步字段信息
     */
    public void syncFieldsFromObjects() {
        if (volunteer != null) {
            this.volunteerName = volunteer.getRealName();
        }

        if (project != null) {
            this.projectName = project.getName();
        }

        if (venue != null) {
            this.venueName = venue.getName();
        }

        // 重新计算服务时长
        this.serviceHours = calculateServiceHours();
    }

    /**
     * 获取所有可能的状态
     */
    public static List<String> getAllStatuses() {
        return Arrays.asList(
                TaskStatus.NOT_STARTED.getDisplayName(),
                TaskStatus.IN_PROGRESS.getDisplayName(),
                TaskStatus.COMPLETED.getDisplayName(),
                TaskStatus.CANCELLED.getDisplayName()
        );
    }

    /**
     * 获取所有可能的评分
     */
    public static List<String> getAllRatings() {
        return Arrays.asList(
                TaskRating.EXCELLENT.getDisplayName(),
                TaskRating.GOOD.getDisplayName(),
                TaskRating.QUALIFIED.getDisplayName(),
                TaskRating.UNQUALIFIED.getDisplayName()
        );
    }

    /**
     * 检查任务信息是否完整
     */
    public boolean isProfileComplete() {
        return volunteerId != null
                && taskContent != null && !taskContent.trim().isEmpty()
                && startTime != null;
    }

    /**
     * 获取任务摘要信息
     */
    public String getTaskSummary() {
        StringBuilder summary = new StringBuilder();
        summary.append("志愿者：").append(volunteerName != null ? volunteerName : "未知").append("\n");
        summary.append("任务类型：").append(getTaskType()).append("\n");
        summary.append("任务内容：").append(taskContent != null ? taskContent : "无").append("\n");
        summary.append("开始时间：").append(startTime != null ? startTime.toString() : "未知").append("\n");
        summary.append("结束时间：").append(endTime != null ? endTime.toString() : "未设定").append("\n");
        summary.append("任务状态：").append(getStatusDisplayName()).append("\n");
        summary.append("服务时长：").append(getServiceHoursDisplay());

        if (rating != null) {
            summary.append("\n任务评分：").append(getRatingDisplayName());
        }

        if (feedback != null && !feedback.trim().isEmpty()) {
            summary.append("\n志愿者反馈：").append(feedback);
        }

        return summary.toString();
    }

    /**
     * 检查任务是否需要提醒
     */
    public boolean needsReminder() {
        return isStartingSoon() || (isCurrentlyActive() && !isCompleted());
    }

    /**
     * 获取任务进度百分比
     */
    public int getProgressPercentage() {
        if (isNotStarted()) return 0;
        if (isCompleted()) return 100;
        if (isInProgress()) {
            // 根据时间进度计算百分比
            if (startTime == null) return 0;

            LocalDateTime now = LocalDateTime.now();
            if (endTime == null) return 50; // 没有结束时间，按50%显示

            Duration total = Duration.between(startTime, endTime);
            Duration elapsed = Duration.between(startTime, now);

            if (total.toMinutes() <= 0) return 0;

            int percentage = (int) ((elapsed.toMinutes() * 100) / total.toMinutes());
            return Math.max(0, Math.min(100, percentage));
        }
        return 0;
    }

    /**
     * 获取任务完成质量
     */
    public String getCompletionQuality() {
        if (!isCompleted()) return "未完成";

        if (rating == null) return "未评分";

        TaskRating ratingEnum = TaskRating.fromDisplayName(rating);
        if (ratingEnum == null) return "评分异常";

        switch (ratingEnum) {
            case EXCELLENT: return "优秀完成";
            case GOOD: return "良好完成";
            case QUALIFIED: return "合格完成";
            case UNQUALIFIED: return "完成质量欠佳";
            default: return "完成";
        }
    }

    /**
     * 检查是否可以评价
     */
    public boolean canEvaluate() {
        return isCompleted() && rating == null;
    }

    /**
     * 检查任务是否超时
     */
    public boolean isOverdue() {
        return endTime != null && endTime.isBefore(LocalDateTime.now()) && !isCompleted() && !isCancelled();
    }

    /**
     * 获取任务执行效率
     */
    public String getExecutionEfficiency() {
        if (!isCompleted()) return "执行中";

        int plannedHours = calculateServiceHours();
        int actualHours = getServiceHoursDisplay() != null ?
            Integer.parseInt(getServiceHoursDisplay().replace(" 小时", "")) : 0;

        if (plannedHours <= 0) return "无法评估";

        double efficiency = (double) plannedHours / actualHours;
        if (efficiency >= 0.9) return "高效";
        if (efficiency >= 0.7) return "正常";
        return "效率偏低";
    }
}